#include <string>

#include "monad.hpp"

// 需求：在只读环境 `Env`、可变状态 `int` 下写日志 `std::string`
struct Env
{
    double factor;
};

// 最内层用 Identity 作为默认 monad
//template <class A>
using MYS1 = StateT<int, int>;
using MYS2 = ReaderT<Env, MYS1>;
using MyStack = WriterT<std::string, MYS2>;  // 注意：StateT<S, A>

// clang-format off
auto computation = MyStack::tell("start\n") >>= [](auto)
{
    return MYS2::ask() >>= [](Env e) {
        return MYS1::get() >>= [e](int s) {
            int n = static_cast<int>(s * e.factor);
            return MyStack::tell("factor applied\n") >> MYS1::put(n) >> mreturn(n);
        };
    };
};
// clang-format on

int main(int argc, char** argv)
{
    // clang-format off
    // 运行 
    auto result = runWriter(
        runReader(            
            runState(computation, 10),  // 初始状态,
                        Env{1.5})); // 环境
                                                // result 类型是 ((int, int), std::string)
    // clang-format on
    return 0;
}
